#include "VSTexture.h"
#include "VSShaderStringFactory.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI_NoCreateFun(VSTexture,VSBind)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_BEGIN(VSTexture)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_END
BEGIN_ADD_PROPERTY(VSTexture,VSBind)
REGISTER_PROPERTY(m_uiFormatType,FormatType,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_uiWidth,Width,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_uiHeight,Height,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_uiLenght,Lenght,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_uiMipLevel,MipLevel,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[0],BufferArray0,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[1],BufferArray1,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[2],BufferArray2,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[3],BufferArray3,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[4],BufferArray4,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[5],BufferArray5,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[6],BufferArray6,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[7],BufferArray7,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[8],BufferArray8,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[9],BufferArray9,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[10],BufferArray10,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[11],BufferArray11,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[12],BufferArray12,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pBufferArray[13],BufferArray13,VSProperty::F_SAVE_LOAD_CLONE);
END_ADD_PROPERTY
VSTexture::VSTexture(unsigned int uiFormatType,unsigned int uiWidth,
					 unsigned int uiHeight,unsigned int uiLength,unsigned int uiMipLevel,bool bIsStatic)
{
	VSMAC_ASSERT(uiWidth && uiHeight);
	VSMAC_ASSERT(uiFormatType < VSRenderer::SFT_MAX);
	m_uiFormatType = uiFormatType;
	m_uiHeight = uiHeight;
	m_uiWidth = uiWidth;
	m_uiLenght = uiLength;
	for (unsigned int i = 0 ; i < MAX_MIP_LEVEL ; i++)
	{
		for (unsigned int j = 0 ; j < 6 ; j++)
		{
			m_pLockDate[i][j] = NULL;
		}
	}

	m_bIsStatic = bIsStatic;
	m_uiMipLevel = uiMipLevel;
	
	
}
VSTexture::VSTexture()
{
	for (unsigned int i = 0 ; i < MAX_MIP_LEVEL ; i++)
	{
		for (unsigned int j = 0 ; j < 6 ; j++)
		{
			m_pLockDate[i][j] = NULL;
		}
	}
		
}
VSTexture::~VSTexture()
{
	ReleaseResource();

}
unsigned int VSTexture::DiskUse()const
{
	unsigned int Use = VSBind::DiskUse();
	

	Use += sizeof(unsigned int) * 5;
	for (unsigned int i = 0 ; i < m_uiMipLevel ; i++)
	{

		Use += m_pBufferArray[i].GetNum();

	}

	return Use;

}
bool VSTexture::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSBind::Save(rStream,iSaveUse))
		return false;

	


	if(!rStream.Write(&m_uiFormatType,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Write(&m_uiWidth,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Write(&m_uiHeight,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Write(&m_uiLenght,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);



	if(!rStream.Write(&m_uiMipLevel,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);


	for (unsigned int i = 0 ; i < m_uiMipLevel ; i++)
	{
		unsigned int uiSize = GetByteSize(i);
		if(!rStream.Write(m_pBufferArray[i].GetBuffer(),uiSize))
			return 0;
		iSaveUse += uiSize;
	}
		


	


	return 1;
}
bool VSTexture::Load(VSStream & rStream,unsigned int &iSaveUse)
{

	if(!VSBind::Load(rStream,iSaveUse))
		return false;

	



	if(!rStream.Read(&m_uiFormatType,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);
	
	if(!rStream.Read(&m_uiWidth,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Read(&m_uiHeight,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Read(&m_uiLenght,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);


	if(!rStream.Read(&m_uiMipLevel,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);


	for (unsigned int i = 0 ; i < m_uiMipLevel ; i++)
	{
		unsigned int uiSize = GetByteSize(i);
		m_pBufferArray[i].SetBufferNum(uiSize);
	
		if(!rStream.Read(m_pBufferArray[i].GetBuffer(),uiSize))
			return 0;
		iSaveUse += uiSize;
	}


	


	return 1;
}
bool VSTexture::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSTexture* Temp = DynamicCast<VSTexture>(pObject); 
	if(!Temp)
		return 0;
	if(VSBind::Clone(pObject,uiType))
	{

		m_uiFormatType = Temp->m_uiFormatType;
		m_uiWidth = Temp->m_uiWidth;
		m_uiHeight =Temp->m_uiHeight;
		m_uiLenght = Temp->m_uiLenght;
		m_uiMipLevel = Temp->m_uiMipLevel;


		for (unsigned int i = 0 ; i < m_uiMipLevel ; i++)
		{
			m_pBufferArray[i] = Temp->m_pBufferArray[i];
		}

		return 1;
	}
	else
	{
		return 0;

	}
}
bool VSTexture::LoadResource(VSRenderer * pRender)
{
	if (!VSBind::LoadResource(pRender))
	{
		return false;
	}
	if (m_uiMemType == MT_VRAM)
	{
		for (unsigned int i = 0 ; i < MAX_MIP_LEVEL ; i++)
		{
			m_pBufferArray[i].Destroy();
		}
	}
	return true;
}
bool VSTexture::OnLoadResource(VSResourceIdentifier *&pID)
{
	if(!m_pUser)
		return 0;
	if(!m_pUser->OnLoadTexture(this,pID))
		return 0;
	return 1;

}
bool VSTexture::OnReleaseResource(VSResourceIdentifier *pID)
{
	if(!m_pUser)
		return 0;
	if(!m_pUser->OnReleaseTexture(pID))
		return 0;
	return 1;
}
void *VSTexture::Lock(unsigned int uiLevel,unsigned int uiFace)
{
	if (m_pLockDate[uiLevel][uiFace] || m_bIsStatic)
	{
		return NULL;
	}
	if (m_pUser)
	{
		m_pLockDate[uiLevel][uiFace] = m_pUser->Lock(this,uiLevel,uiFace);
	}

	return m_pLockDate[uiLevel][uiFace];
}
void VSTexture::UnLock(unsigned int uiLevel,unsigned int uiFace)
{
	if (!m_pLockDate[uiLevel][uiFace] || m_bIsStatic)
	{
		return;
	}
	if (m_pUser)
	{
		m_pUser->UnLock(this,uiLevel,uiFace);
	}
	m_pLockDate[uiLevel][uiFace] = NULL;
}
void VSTexture::CreateRAMDate()
{
	for (unsigned int i = 0 ; i < m_uiMipLevel ; i++)
	{
		m_pBufferArray[i].SetBufferNum(GetByteSize(i));
	}
}